#!/usr/bin/env python3
#! -*- coding: utf-8 -*-

import os
import re
import subprocess
from typing import Dict, List, Tuple
from functools import cmp_to_key

# Path to Linux Kernel Source Root
kernel_src_root = './linux'

TABLE_TEMPLATE = '''<table style="text-align: center">
    <thead>
        <tr>
            <th>主架构名称</th>
            <th><code>uname -m</code> 可选的返回值</th>
        </tr>
    </thead>
    <tbody>
        {tbody}
    </tbody>
</table>
'''

kernel_src_root = os.path.abspath(kernel_src_root)
result_dic: Dict[str, List[str]] = dict()

# Folder
arch_root = os.path.join(kernel_src_root, 'arch')
item_lis = os.listdir(arch_root)
for item in item_lis:
    if os.path.isdir(os.path.join(arch_root, item)):
        if item not in result_dic:
            result_dic[item] = list()
        if item not in result_dic[item]:
            result_dic.get(item).append(item)

# UTS_MACHINE
exp = r'arch/(?P<mainArch>[^/]+)/Makefile:\s*UTS_MACHINE\s*:=\s*(?P<arch>\S+)'
patt = re.compile(exp, re.I)
proc = subprocess.Popen(['git', 'grep', 'UTS_MACHINE\s*:='], cwd=kernel_src_root, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
out = out.decode('utf-8')
for line in out.splitlines():
    res = re.match(patt, line.strip())
    if res is None:
        print("Match failed: {}".format(line))
        continue
    dic: Dict[str, str] = res.groupdict()
    if '$' in dic.get('arch'):
        continue
    if dic.get('mainArch') not in result_dic:
        result_dic[dic.get('mainArch')] = list()
    if dic.get('arch') not in result_dic[dic.get('mainArch')]:
        result_dic[dic.get('mainArch')].append(dic.get('arch'))

# COMPAT_UTS_MACHINE
exp = r'arch/(?P<mainArch>[^/]+)/[^:]*:\s*#define\s*COMPAT_UTS_MACHINE\s*"(?P<arch>[A-Za-z0-9_\-]+)'
patt = re.compile(exp, re.I)
proc = subprocess.Popen(['git', 'grep', '#define\s*COMPAT_UTS_MACHINE'], cwd=kernel_src_root, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
out = out.decode('utf-8')
for line in out.splitlines():
    res = re.match(patt, line.strip())
    if res is None:
        print("Match failed: {}".format(line))
        continue
    dic: Dict[str, str] = res.groupdict()
    if dic.get('mainArch') not in result_dic:
        result_dic[dic.get('mainArch')] = list()
    if dic.get('arch') not in result_dic[dic.get('mainArch')] and \
        '{} (compat)'.format(dic.get('arch')) not in result_dic[dic.get('mainArch')]:
        result_dic[dic.get('mainArch')].append('{} (compat)'.format(dic.get('arch')))

def cmp(s1: str, s2: str):
    if len(s2) > len(s1):
        return -1
    elif len(s2) < len(s1):
        return 1
    else:
        return 1 if s1 > s2 else \
            -1 if s1 < s2 else \
            0

result_lis = list(result_dic.items())
result_lis.sort(key=lambda x: x[0])

i = 0
tbody = ''

for i in range(len(result_lis)):
    main_name, name_lis = result_lis[i]
    name_lis.sort(key=cmp_to_key(cmp))
    tr = '<tr>'
    tr += '<td>{}</td>'.format(main_name)
    tr += '<td><code>{}</code></td>'.format(
        '</code>, <code>'.join(name_lis)
    )
    tr += '</tr>'
    tbody += tr

final_res = TABLE_TEMPLATE.format(tbody=tbody)
print(final_res)

